import { Vector2tuple } from 'three-legacy';
import { DimLinear } from '../dimension/DimLinear';
import { DimRadiusTool } from '../dimension/DimRadiusTool';
import { DimDiameterTool } from '../dimension/DimDiameter';
import { DimAngleTool } from '../dimension/DimAngleTool';
import { DimEllipseTool } from '../dimension/DimEllipseRadius';
import { dimRender } from './render';
import { ICurve } from '@amcax/base';
import { AnnotationType } from '../dimension/types';

export type DimInfo = {
  id?: string;
  objects?: string[];
  type: AnnotationType;
  points?: Vector2tuple[];
  value?: number;
  curveIds?: string[];
  implict?: boolean; // 是否为隐含标注
  master?: boolean; // 是否为主标注
  disabled?: boolean;
  param?: string;
};

export type AnnotationData = {
  id?: string;
  type: AnnotationType;
  points?: Vector2tuple[];
  value?: number;
  implict?: boolean; // 是否为隐含标注
  master?: boolean; // 是否为主标注
  target?: string;
  curve?: string;
  param?: string;
};

export type GroupsType = {
  groupid: string;
  idx: number;
  type: string;
};
export type CurveMap = Map<string, ICurve & { groups?: GroupsType[] }>;
export type DimMap = Map<string, DimInfo>;

export type DimObject =
  | DimLinear
  | DimRadiusTool
  | DimDiameterTool
  | DimRadiusTool
  | DimAngleTool
  | DimEllipseTool;

export function formatDim() {
  const dims = [];
  dimRender()
    .getDimMap()
    .forEach((item) => {
      dims.push(...lineTramsformPoint(item.objects, item.type).dim);
    });
  return dims;
}

const condit_fn = (item) =>
  item.type === 'Rect' || item.type.includes('Polygon');

export function lineTramsformPoint(objects: string[], type: number) {
  const dim = []; // 标注信息
  const linePotIds = []; // 标注的线的两端点的id
  const lineIds = []; // 标注的线的id
  let pointIds = [];
  const LinePoints = [];
  const PointPoints = [];
  const groupsAngle = [];
  objects.forEach((id) => {
    const curve = dimRender().getSketMap().get(id);
    const group = curve?.['groups'];
    if (group?.length > 0 && group.some(condit_fn)) {
      if (type === AnnotationType.AngleAnno) {
        groupsAngle.push(group);
      } else {
        if (curve?.type === 'Line') {
          linePotIds.push(curve.relative[0], curve.relative[1]);
          LinePoints.push(curve.vertices);
          lineIds.push(curve.id);
        } else {
          PointPoints.push(curve.vertices);
          pointIds.push(curve.id);
        }
      }
    } else {
      pointIds.push(curve?.id ?? id);
      if (curve?.type === 'Line') {
        lineIds.push(curve.id);
      }
    }
  });
  const dists = [];
  if (LinePoints.length > 0 && PointPoints.length > 0) {
    LinePoints[0].forEach((item) => {
      dists.push(calculateDistance(item, PointPoints[0][0]));
    });
    pointIds = [linePotIds[dists[0] < dists[1] ? 0 : 1], pointIds[0]];
    dim.push(...addDimObj(pointIds, type));
  } else if (LinePoints.length === 2) {
    LinePoints[0].forEach((item) => {
      dists.push(calculateDistance(item, LinePoints[1][0]));
    });
    pointIds = [linePotIds[dists[0] < dists[1] ? 0 : 1], linePotIds[2]];
    dim.push(...addDimObj(pointIds, type));
  }
  return { dim, pointIds, groupsAngle, lineIds };
}

function addDimObj(objects, type) {
  return [
    objects[0] + ',' + objects[1] + '-' + type,
    objects[1] + ',' + objects[0] + '-' + type,
  ];
}

function calculateDistance(point1, point2) {
  const x1 = point1[0];
  const y1 = point1[1];
  const x2 = point2[0];
  const y2 = point2[1];

  return (x2 - x1) ** 2 + (y2 - y1) ** 2;
}

// // no usage, commented out to avoid linting errors
// export function formatEqualCon(equalCons) {
// // linting errors for unused expressions
//   equalCons;
// }

export function groupConnectedElements(arrays) {
  // 创建一个图，键是元素，值是与该元素相连的其他元素
  const graph = new Map();

  // 构建图
  arrays.forEach((arr) => {
    for (let i = 0; i < arr.length; i++) {
      if (!graph.has(arr[i])) {
        graph.set(arr[i], new Set());
      }
      for (let j = 0; j < arr.length; j++) {
        if (i !== j) {
          graph.get(arr[i]).add(arr[j]);
        }
      }
    }
  });

  // 用来存储已访问的节点
  const visited = new Set();

  // 深度优先搜索（DFS）函数
  function dfs(node) {
    const group = [];
    const stack = [node];
    visited.add(node);

    while (stack.length > 0) {
      const current = stack.pop();
      group.push(current);

      graph.get(current).forEach((neighbor) => {
        if (!visited.has(neighbor)) {
          visited.add(neighbor);
          stack.push(neighbor);
        }
      });
    }

    return group;
  }

  // 存储所有的分组
  const result = [];

  // 遍历图中的所有节点
  for (const node of graph.keys()) {
    if (!visited.has(node)) {
      const group = dfs(node);
      result.push(group);
    }
  }

  return result;
}
